﻿using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using OBS;
using OBS.Model;

namespace CRM.Services
{
    public class UploadService : BaseService
    {
        private readonly ILogger<UploadService> _logger;

        //定义图片数组后缀格式
        string[] LimitPictureType = {
            ".IMAGE/BMP",
            ".IMAGE/GIF",
            ".IMAGE/JPEG",
            ".IMAGE/PNG",
            ".IMAGE/X-ICON",
            ".ICO",
            ".IMAGE/VND.MICROSOFT.ICON",
            ".BMP",
            ".GIF",
            ".JPEG",
            ".PNG",
            ".JPG"
        };

        public UploadService(ILogger<UploadService> logger)
        {
            _logger = logger;
        }

        /// <summary>
        /// 单图片上传
        /// </summary>
        /// <param name="FileFolder">本地存储路径</param>
        /// <param name="FormFile">[FromForm] IFormCollection FormFile</param>
        /// <returns></returns>
        public async Task<ResultObject> UploadSingleImg(string FileFolder, IFormCollection FormFile)
        {
            if (Directory.Exists(FileFolder) == false)
            {
                Directory.CreateDirectory(FileFolder);
            }

            FormFileCollection FileCollection = (FormFileCollection)FormFile.Files;
            IFormFile File = FileCollection[0];

            //foreach (IFormFile file in fileCollection)

            //获取图片后缀是否存在数组中
            string currentPictureExtension = Path.GetExtension(File.FileName).ToUpper();
            if (LimitPictureType.Contains(currentPictureExtension))
            {
                var FileName = $"{DateTime.Now.ToString("yyyyMMddHHmmss")}{Path.GetExtension(File.FileName)}";
                var FilePath = Path.Combine(FileFolder, FileName);
                using (var stream = new FileStream(FilePath, FileMode.Create))
                {
                    await File.CopyToAsync(stream);
                }
                var Res = UploadSingleFile("oem/" + FileName, FilePath);
                if (Res.State)
                {
                    //删除文件
                    System.IO.File.Delete(FilePath);
                }
                return Res;
            }
            return new ResultObject
                {
                    State = false,
                    Data = "请上传指定格式的图片",
                    Message = ""
                }; 
        }






        //************************* 华为云OBS测试 START  *******************//
        //文档 https://support.huaweicloud.com/sdk-dotnet-devg-obs/obs_25_0001.html

        /// <summary>
        /// 
        /// </summary>
        /// <param name="FileName">obs访问域名后地址</param>
        /// <param name="LocalFilename">SourceCode 内相对路径</param>
        /// <returns></returns>
        public ResultObject UploadSingleFile(string FileName, string LocalFilename)
        {
            // 创建ObsClient实例
            ObsClient client = new ObsClient("R3N0LKJQRBOOAW66SMSM", "YZed89ffuYa2X04cjlXivWukBSPOtInj9kgUhkYQ", "https://obs.cn-east-3.myhuaweicloud.com");
            // 上传文件
            try
            {
                PutObjectRequest request = new PutObjectRequest()
                {
                    BucketName = "erp4res",
                    ObjectKey = FileName,//obs上传路径
                    FilePath = LocalFilename,//待上传的本地文件路径，需要指定到具体的文件名
                };
                PutObjectResponse response = client.PutObject(request);
                ResultObject res = new ResultObject
                {
                    State = true,
                    Data = "https://erp4res.obs.cn-east-3.myhuaweicloud.com/" + FileName,
                    Message = response.StatusCode
                };

                return res;
                //Console.WriteLine("put object response: {0}", response.StatusCode);
            }
            catch (ObsException ex)
            {
                _logger.LogError(ex, "上传图片至obs");
                ResultObject res = new ResultObject
                {
                    State = false,
                    Data = ex.ErrorMessage,
                    Message = ex.ErrorCode
                };

                return res;
                //Console.WriteLine("ErrorCode: {0}", ex.ErrorCode);
                //Console.WriteLine("ErrorMessage: {0}", ex.ErrorMessage);
            }
        }

        /// <summary>
        /// 单文件删除
        /// </summary>
        /// <param name="ObsPath">obs访问域名后地址</param>
        /// <returns></returns>
        public ResultObject DelObsFile(string ObsPath)
        {
            // 创建ObsClient实例
            ObsClient client = new ObsClient("R3N0LKJQRBOOAW66SMSM", "YZed89ffuYa2X04cjlXivWukBSPOtInj9kgUhkYQ", "https://obs.cn-east-3.myhuaweicloud.com");
            // 删除对象
            try
            {
                DeleteObjectRequest request = new DeleteObjectRequest()
                {
                    BucketName = "erp4res",
                    ObjectKey = ObsPath//obs上传路径
                };
                DeleteObjectResponse response = client.DeleteObject(request);

                ResultObject res = new ResultObject
                {
                    State = true,
                    Data = "",
                    Message = response.StatusCode
                };

                return res;
                //Console.WriteLine("Delete object response: {0}", response.StatusCode);
            }
            catch (ObsException ex)
            {
                ResultObject res = new ResultObject
                {
                    State = false,
                    Data = ex.ErrorMessage,
                    Message = ex.ErrorCode
                };

                return res;

                //Console.WriteLine("ErrorCode: {0}", ex.ErrorCode);
                //Console.WriteLine("ErrorMessage: {0}", ex.ErrorMessage);
            }
        }

        /// <summary>
        /// 断点续传
        /// </summary>
        /// <param name="ObsPath">obs域名后地址</param>
        /// <param name="LocalFilename">SourceCode 内相对路径temporary/avatar/</param>
        /// <returns></returns>
        public ResultObject BreakPointUploadFile(string ObsPath, string LocalFilename) {
            // 创建ObsClient实例
            ObsClient client = new ObsClient("R3N0LKJQRBOOAW66SMSM", "YZed89ffuYa2X04cjlXivWukBSPOtInj9kgUhkYQ", "https://obs.cn-east-3.myhuaweicloud.com");
            // 断点续传上传文件
            try
            {
                UploadFileRequest request = new UploadFileRequest
                {
                    BucketName = "erp4res",
                    ObjectKey = ObsPath,//obs上传路径
                    // 待上传的本地文件路径
                    UploadFile = LocalFilename,
                    // 上传段大小为10MB
                    UploadPartSize = 10 * 1024 * 1024,
                    // 开启断点续传模式
                    EnableCheckpoint = true,
                };
                // 以传输字节数为基准反馈上传进度
                request.ProgressType = ProgressTypeEnum.ByBytes;
                // 每上传1MB数据反馈上传进度
                request.ProgressInterval = 1024 * 1024;

                // 注册上传进度回调函数
                request.UploadProgress += delegate (object sender, TransferStatus status) {
                    // 获取上传平均速率
                    Console.WriteLine("AverageSpeed: {0}", status.AverageSpeed / 1024 + "KB/S");
                    // 获取上传进度百分比
                    Console.WriteLine("TransferPercentage: {0}", status.TransferPercentage);
                };

                // 注册上传事件回调函数
                request.UploadEventHandler += delegate (object sender, ResumableUploadEvent e) {
                    // 获取上传事件
                    Console.WriteLine("EventType: {0}", e.EventType);
                };

                CompleteMultipartUploadResponse response = client.UploadFile(request);
                ResultObject res = new ResultObject
                {
                    State = true,
                    Data = "",
                    Message = response.StatusCode
                };

                return res;
                //Console.WriteLine("Upload File response: {0}", response.StatusCode);
            }
            catch (ObsException ex)
            {
                ResultObject res = new ResultObject
                {
                    State = false,
                    Data = ex.ErrorMessage,
                    Message = ex.ErrorCode
                };

                return res;
                //Console.WriteLine("ErrorCode: {0}", ex.ErrorCode);
                //Console.WriteLine("ErrorMessage: {0}", ex.ErrorMessage);
            }
        }


        public struct ResultObject
        {
            public object Message { get; set; }
            public object Data { get; set; }
            public Boolean State { get; set; }
        }
        //************************* 华为云OBS测试 END  *******************//
    }
}
